home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / uupc11ys.zip / LIB / NDIR.C < prev    next >
C/C++ Source or Header  |  1993-04-04  |  6KB  |  185 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    n d i r . c                                                     */
  3. /*                                                                    */
  4. /*    Berkeley-style directory reading routine on MS-DOS by Samuel    */
  5. /*    Lam <skl@van-bc.UUCP>, June/87                                  */
  6. /*                                                                    */
  7. /*    Changes Copyright (c) 1990, 1991 by Andrew H. Derbyshire        */
  8. /*--------------------------------------------------------------------*/
  9.  
  10. /*--------------------------------------------------------------------*/
  11. /*                   Standard library include files                   */
  12. /*--------------------------------------------------------------------*/
  13.  
  14. #include <stdio.h>
  15. #include <ctype.h>
  16. #include <string.h>
  17. #include <dos.h>
  18. #include <stdlib.h>
  19. #include <time.h>
  20.  
  21. /*--------------------------------------------------------------------*/
  22. /*                    UUPC/extended include files                     */
  23. /*--------------------------------------------------------------------*/
  24.  
  25. #include "lib.h"
  26. #include "uundir.h"
  27. #include "getdta.h"
  28.  
  29. #include "dos2unix.h"
  30.  
  31. #ifndef __TURBOC__
  32. #include "getdta.h"           /* Custom versions of Disk Xfer Addr
  33.                                  functions for MS environment only   */
  34. #endif
  35.  
  36. /*--------------------------------------------------------------------*/
  37. /*                          Global variables                          */
  38. /*--------------------------------------------------------------------*/
  39.  
  40. currentfile();
  41.  
  42. /*--------------------------------------------------------------------*/
  43. /*    o p e n d i r x                                                 */
  44. /*                                                                    */
  45. /*    Open a directory                                                */
  46. /*--------------------------------------------------------------------*/
  47.  
  48. extern DIR *opendirx( const char *dirname, char *pattern)
  49. {
  50.    union REGS inregs, outregs;
  51.    struct SREGS segregs;
  52.    char pathname[FILENAME_MAX];
  53.    DTA far *dtasave;
  54.    DTA far *dtaptr;
  55.    char far *pathptr;
  56.    DIR *dirp;
  57.  
  58. /*--------------------------------------------------------------------*/
  59. /*                    Build pathname to be scanned                    */
  60. /*--------------------------------------------------------------------*/
  61.  
  62.    strcpy(pathname, dirname);
  63.    if ((*pattern != '/') || (dirname[ strlen(dirname) - 1] != '/'))
  64.       strcat(pathname,"/");
  65.    strcat(pathname, pattern);
  66.  
  67.    /* allocate control block */
  68.    dirp = malloc(sizeof(DIR));
  69.  
  70. /*--------------------------------------------------------------------*/
  71. /*                     Set disk transfer address                      */
  72. /*--------------------------------------------------------------------*/
  73.  
  74.    dtasave = (DTA far *)getdta();
  75.    dtaptr = (DTA far *)&(dirp->dirdta);
  76.    setdta((char far *)dtaptr);
  77.  
  78. /*--------------------------------------------------------------------*/
  79. /*                      look for the first file                       */
  80. /*--------------------------------------------------------------------*/
  81.  
  82.    inregs.h.ah = 0x4e;
  83.    pathptr = (char far *)pathname;
  84.    segregs.ds = FP_SEG(pathptr);
  85.    inregs.x.dx = FP_OFF(pathptr);
  86.    inregs.x.cx = 0;   /* attribute */
  87.    intdosx(&inregs, &outregs, &segregs);
  88.  
  89.    /* bad directory name? */
  90.    if (outregs.x.cflag && (outregs.x.ax == 2 || outregs.x.ax == 3)) {
  91.       free(dirp);
  92.       return NULL;
  93.    }
  94.  
  95.    dirp->dirfirst = outregs.x.cflag ? outregs.x.ax : 0;
  96.  
  97.    setdta((char far *)dtasave);
  98.    strcpy(dirp->dirid, "DIR");
  99.  
  100.    return dirp;
  101.  
  102. } /*opendir*/
  103.  
  104.  
  105. /*--------------------------------------------------------------------*/
  106. /*    r e a d d i r                                                   */
  107. /*                                                                    */
  108. /*    Get next entry in a directory                                   */
  109. /*--------------------------------------------------------------------*/
  110.  
  111. struct direct *readdir(DIR *dirp)
  112. {
  113.    int errcode;
  114.  
  115.    if (!equal(dirp->dirid, "DIR"))
  116.    {
  117.       printmsg(0,"Unexpected readdir call; no search in progress");
  118.       panic();
  119.    }
  120.  
  121.    if (dirp->dirfirst == -1) {
  122.       union REGS inregs, outregs;
  123.       struct SREGS segregs;
  124.       DTA far *dtaptr;
  125.       DTA far *dtasave;
  126.  
  127.      /* set DTA address to our buffer each time we're called */
  128.       dtasave = (DTA far *)getdta();
  129.       dtaptr = (DTA far *)&(dirp->dirdta);
  130.       setdta((char far *)dtaptr);
  131.  
  132.       inregs.h.ah = 0x4f;
  133.       segregs.ds = FP_SEG(dtaptr);
  134.       inregs.x.dx = FP_OFF(dtaptr);
  135.       intdosx(&inregs, &outregs, &segregs);
  136.       errcode = outregs.x.cflag ? outregs.x.ax : 0;
  137.  
  138.       setdta((char far *)dtasave);  /* Restore DTA address     */
  139.  
  140.    } else {
  141.  
  142.       errcode = dirp->dirfirst;
  143.       dirp->dirfirst = -1;
  144.  
  145.    };
  146.  
  147.    /* no more files in directory? */
  148.    if (errcode == 18)
  149.       return NULL;
  150.  
  151.    if ( errcode != 0)
  152.    {
  153.       errno = errcode;
  154.       printerr( "readdir" );
  155.       panic();
  156.    }
  157.  
  158.    dirp->dirent.d_ino = -1;   /* no inode information */
  159.    strlwr(strcpy(dirp->dirent.d_name, dirp->dirdta.filename));
  160.    dirp->dirent.d_namlen = strlen(dirp->dirent.d_name);
  161.    dirp->dirent.d_reclen = sizeof(struct direct) - (MAXNAMLEN + 1) +
  162.       ((((dirp->dirent.d_namlen + 1) + 3) / 4) * 4);
  163.  
  164.    dirp->dirent.d_modified = dos2unix( dirp->dirdta.filedate,
  165.                                         dirp->dirdta.filetime );
  166.    dirp->dirent.d_size     = dirp->dirdta.filesize;
  167.  
  168.    return &(dirp->dirent);
  169.  
  170. } /*readdir*/
  171.  
  172. /*--------------------------------------------------------------------*/
  173. /*    c l o s e d i r                                                 */
  174. /*                                                                    */
  175. /*    Close a directory                                               */
  176. /*--------------------------------------------------------------------*/
  177.  
  178. void closedir(DIR *dirp)
  179. {
  180.  
  181.    strcpy(dirp->dirid, "XXX");
  182.    free(dirp);
  183.  
  184. } /*closedir*/
  185.